import mimetypes
import os
import re
import urllib.parse
from datetime import datetime
from wsgiref.util import FileWrapper

from django.db.models import Q
from django.http import JsonResponse, StreamingHttpResponse
from django.shortcuts import render, redirect, reverse
from django.views.generic import View
from pure_pagination import Paginator, PageNotAnInteger

from Jv.settings import BASE_DIR
from my_apps.user.models import UserProfile, UserFavorite
from utils.file_iterator import file_iterator
from .models import Video, VideoSub, VideoComment, VideoStar, VideoHistory, video_type, nation_type, UserGiveLikes


class HomeView(View):
    """主页 显示所有视频"""

    def get(self, request):
        data = {}
        if request.user.is_authenticated:
            user = UserProfile.objects.get(
                username=request.user.username
            )
            data['username'] = user.username

        data['page_name'] = 'home'
        #  所有番剧
        data["all_fan_video"] = Video.objects.all().exclude(video_type='15')
        #  所有用户上传视频
        data["all_user_video"] = Video.objects.filter(video_type='15').order_by('?')[:2]
        # 精品视频
        data['good_videos'] = Video.objects.filter(is_good=True)[:4]
        #  时间倒序
        data["desc_date_video"] = Video.objects.all().order_by("-add_time")[:8]
        return render(request, 'main_hub/home.html', data)


class CartoonView(View):
    """番剧页"""

    def get(self, request):
        data = {}
        if request.user.is_authenticated:
            user = UserProfile.objects.get(
                username=request.user.username
            )
            data['username'] = user.username
        city = request.GET.get('city')
        category = request.GET.get('ct')
        order = request.GET.get('order')

        all_video = Video.objects.all().exclude(video_type='15')

        if category:
            data['category'] = int(category)
            all_video = all_video.filter(video_type=category)  # 按类别分
        data['video_type'] = video_type

        if city:
            data['city'] = int(city)
            all_video = all_video.filter(nationality_type=city)  # 按国家分
        data['city_type'] = nation_type

        video_list = all_video.order_by('-add_time')
        # 排序
        if order:
            data['order'] = order
            if order == "hot":
                video_list = all_video.order_by("-mood")
            if order == "time":
                video_list = all_video.order_by("-add_time")

        # 分页
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        p = Paginator(video_list, per_page=40, request=request)
        all_video = p.page(page)
        data['all_video'] = all_video
        data['page_name'] = 'cartoon'
        return render(request, 'main_hub/cartoon.html', data)


class TvView(View):
    """电视剧页"""

    def get(self, request):
        data = {}
        data['page_name'] = 'tv'
        return render(request, 'main_hub/tv.html', data)


class AtvView(View):
    """美剧页"""

    def get(self, request):
        data = {}
        data['page_name'] = 'atv'
        return render(request, 'main_hub/atv.html', data)


class VideoDetailView(View):
    """视频观看页"""

    def get(self, request, video_id):
        data = {}
        # 获取视频
        try:
            video = Video.objects.get(id=video_id)
            data['video'] = video
            video.mood += 1
            video.save()
        except:
            return redirect(reverse("home"))

        # 获取集数
        video_sub_number = request.GET.get('video_sub_number')

        if not video_sub_number:
            video_sub_number = 1
        # 获取这个视频的某一集
        try:
            video_sub = VideoSub.objects.get(video=video, number=video_sub_number)
            data['video_sub'] = video_sub
        except:
            return redirect(reverse('home'))

        # 收藏状态
        fav_video = False
        fav_user = False
        # 点赞状态
        like_video = False

        if request.user.is_authenticated:
            # 删除多余记录
            self.history_save(request.user, video=video, sub=video_sub_number)
            self.del_history(request.user)

            if UserFavorite.objects.filter(user=request.user, fav_id=video.id, fav_type='1'):
                fav_video = True
            if UserFavorite.objects.filter(user=request.user, fav_id=video.user.id, fav_type='2'):
                fav_user = True
            if UserGiveLikes.objects.filter(user=request.user, video=video, video_sub=video_sub, like_type='1'):
                like_video = True

        data['fav_user'] = fav_user
        data['fav_video'] = fav_video
        data['like_video'] = like_video

        # 获取这个视频的所有集数
        data['all_video_subs'] = VideoSub.objects.filter(video=video_id)

        # 这个视频的所有评论
        all_comments = VideoComment.objects.filter(video=video, video_sub__number=video_sub_number).order_by(
            '-add_time')[:10]
        data['all_comments'] = all_comments
        data['page_num'] = 1
        # 这个视频的所有演员
        data['all_stars'] = VideoStar.objects.filter(video=video_id)

        return render(request, 'main_hub/video_detail.html', data)

    def history_save(self, user, video, sub):
        """视频记录存储"""
        vid_hty = VideoHistory.objects.filter(user=user, video=video, sub=sub)
        if vid_hty:
            vid_hty.modify_time = datetime.now()
        else:
            VideoHistory.objects.create(user=user, video=video, sub=sub)

    def del_history(self, user):
        """
        历史记录自动删除一部分
        """
        # 如果此用户的所有历史记录大于一定数量
        if VideoHistory.objects.filter(user=user).count() > 40:
            vs = VideoHistory.objects.filter(user=user).order_by('-modify_time')
            for i in vs[40:]:
                i.delete()


class GetVideoComment(View):
    """获取视频评论"""

    def post(self, request):
        page_num = request.POST.get('page_num', '1')
        video_sub_id = request.POST.get('video_sub_id')
        page_size = 10
        try:
            current_page = int(page_num)
            start_row = (current_page - 1) * page_size
            end_row = current_page * page_size
            video_sub = VideoSub.objects.get(id=video_sub_id)
        except:
            return JsonResponse({
                'status': 'fail',
                'msg': '参数错误'
            })
        video_comment = VideoComment.objects.filter(video_sub=video_sub).order_by('-add_time').values(
            'user__nick_name', 'user__username',
            'user__image', 'comment',
            'add_time')[start_row: end_row]

        return JsonResponse({
            'status': 'success',
            'comment': list(video_comment),
            'page': current_page
        })


class VideoStream(View):
    """流式传输视频"""

    def get(self, request, id):
        try:
            url = VideoSub.objects.get(id=id).user_field.url
        except:
            return render(request, 'main_hub/home.html')
        # 此为我的视频路径
        path = os.path.join(BASE_DIR) + urllib.parse.unquote(url)

        range_header = request.META.get('HTTP_RANGE', '').strip()
        range_re = re.compile(r'bytes\s*=\s*(\d+)\s*-\s*(\d*)', re.I)
        range_match = range_re.match(range_header)
        size = os.path.getsize(path)
        content_type, encoding = mimetypes.guess_type(path)
        content_type = content_type or 'application/octet-stream'
        if range_match:
            first_byte, last_byte = range_match.groups()
            if first_byte:
                first_byte = int(first_byte)
            else:
                first_byte = 0
            last_byte = first_byte + 1024 * 1024 * 8  # 8M per piece, the maximum volume of the response body
            if last_byte > size:
                last_byte = size - 1
            length = last_byte - first_byte + 1
            resp = StreamingHttpResponse(file_iterator(path, offset=first_byte, length=length), status=206,
                                         content_type=content_type)
            resp['Content-Length'] = str(length)
            resp['Content-Range'] = 'bytes %s-%s/%s' % (first_byte, last_byte, size)
        else:
            # When the video stream is not obtained, the entire file is returned in the generator mode to save memory.
            resp = StreamingHttpResponse(FileWrapper(open(path, 'rb')), content_type=content_type)
            resp['Content-Length'] = str(size)
        resp['Accept-Ranges'] = 'bytes'
        return resp


class AddLikes(View):
    """点赞功能"""

    def post(self, request):
        if not request.user.is_authenticated:
            return JsonResponse({
                'status': 'fail',
                'msg': '用户未登录'
            })
        data_id = request.POST.get('data_id')
        like_type = request.POST.get('like_type')
        if like_type == "1":  # 1 为视频
            try:
                video_sub = VideoSub.objects.get(id=data_id)
            except:
                return JsonResponse({
                    'status': 'fail',
                    'msg': '参数错误'
                })
            user_like = UserGiveLikes.objects.filter(
                user=request.user,
                video=video_sub.video,
                video_sub=video_sub,
                like_type=like_type)
            if user_like:
                # 取消点赞
                user_like.delete()
                if data_id:
                    video_sub.likes -= 1
                    video_sub.save()
                    num = video_sub.likes
                    return JsonResponse({
                        'status': 'success',
                        'msg': '已取消',
                        'num': num
                    })
                return JsonResponse({
                    'status': 'fail',
                    'msg': '错误',
                })
            else:
                # 点赞
                user_like = UserGiveLikes.objects.create(
                    user=request.user,
                    like_type=like_type,
                    video=video_sub.video,
                    video_sub=video_sub)
                user_like.save()
                video_sub.likes += 1
                video_sub.save()
                num = video_sub.likes
                return JsonResponse({
                    'status': 'success',
                    'msg': '已点赞',
                    'num': num
                })
        elif like_type == "2":
            # 评论点赞
            pass
        return JsonResponse({
            'status': 'fail',
            'msg': '未知错误'
        })


class AddComment(View):
    """用户评论视频功能"""

    def post(self, request):
        if not request.user.is_authenticated:
            return JsonResponse({
                'status': 'fail',
                'msg': '用户未登录'
            })
        comment = request.POST.get('comment')

        if not comment:
            return JsonResponse({
                'status': 'fail',
                'msg': '评论不能为空'
            })
        video_id = request.POST.get('video')
        video_sub = request.POST.get('video_sub')
        if not video_sub or not video_id:
            return JsonResponse({
                'status': 'fail',
                'msg': '参数错误'
            })
        video = Video.objects.get(id=video_id)
        video_sub = VideoSub.objects.filter(video=video, number=video_sub)
        vc = VideoComment.objects.create(
            user=request.user,
            video=video,
            video_sub=video_sub[0],
            comment=comment
        )
        time = vc.add_time.strftime('%Y{}%m{}%d{} %H:%M').format('年', '月', '日')
        username = vc.user.username
        nick_name = vc.user.nick_name
        img = vc.user.image.url
        return JsonResponse({
            'status': 'success',
            'msg': 'ok',
            'username': username,
            'nick_name': nick_name,
            'img': img,
            'time': time
        })


class SearchVideoView(View):
    """视频搜索"""

    def get(self, request):
        data = {}
        keyword = request.GET.get('keyword', '')
        page_name = request.GET.get('page_name', 'video')
        if keyword == '':
            return redirect(reverse('home'))
        data['page_name'] = page_name
        data['keyword'] = keyword

        # 获取视频
        video_list = Video.objects.filter(name__icontains=keyword).order_by('-start_time')
        # 分页
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        p = Paginator(video_list, per_page=20, request=request)
        all_video = p.page(page)
        data['all_video'] = all_video
        return render(request, 'main_hub/search_video.html', data)


class SearchUserView(View):
    """用户搜索"""

    def get(self, request):
        data = {}
        keyword = request.GET.get('keyword', '')
        page_name = request.GET.get('page_name', 'user')
        if keyword == '':
            return redirect(reverse('home'))
        data['page_name'] = page_name
        data['keyword'] = keyword

        # 搜索用户
        user_list = UserProfile.objects.filter(
            Q(username__icontains=keyword) | Q(nick_name__icontains=keyword)).order_by('-date_joined')
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        p = Paginator(user_list, per_page=20, request=request)
        all_user = p.page(page)
        data['all_user'] = all_user
        return render(request, 'main_hub/search_user.html', data)
